package com.tuocent.dagv2.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tuocent.dagv2.common.AjaxResult;
import com.tuocent.dagv2.common.entity.LoginUserInfo;
import com.tuocent.dagv2.common.utils.SnowFlakeID;
import com.tuocent.dagv2.common.utils.redis.RedisCache;
import com.tuocent.dagv2.entity.ArchivesClassify;
import com.tuocent.dagv2.entity.ArchivesCodeFormat;
import com.tuocent.dagv2.entity.ArchivesCodeList;
import com.tuocent.dagv2.entity.FieldConfig;
import com.tuocent.dagv2.mapper.ArchivesCodeListMapper;
import com.tuocent.dagv2.service.IArchivesClassifyService;
import com.tuocent.dagv2.service.IArchivesCodeFormatService;
import com.tuocent.dagv2.service.IArchivesCodeListService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tuocent.dagv2.service.IFieldConfigService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.ui.Model;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Vincent
 * @since 2025-07-29
 */
@Service
public class ArchivesCodeListServiceImpl extends ServiceImpl<ArchivesCodeListMapper, ArchivesCodeList> implements IArchivesCodeListService {

    @Resource
    private SnowFlakeID snowFlakeID;
    @Resource
    private RedisCache redis;
    @Autowired
    private IFieldConfigService fieldConfigService;
    @Autowired
    private IArchivesCodeFormatService archivesCodeFormatService;
    @Autowired
    private IArchivesClassifyService classifyService;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public AjaxResult getArchivesFormatCodeList(String pid, String action) {
        if ("remove".equals(action)) {
            remove(new QueryWrapper<ArchivesCodeList>().eq("isenter", 0));
        }
        return AjaxResult.success(list(new QueryWrapper<ArchivesCodeList>()
                .eq("pid", pid)
                .eq("isdel", 0)
                .orderByAsc("idx")));
    }

    @Override
    public String setArchivesCodeFormat(Model model, String id, String pid, String classifyId, String children, String codeModel, String parentId) {
        //获取字段配置
        List<FieldConfig> fieldConfigs = fieldConfigService.getFieldConfig(classifyId, codeModel);
        ArchivesCodeList data = getById(id);
        if (data == null) {
            data = new ArchivesCodeList();
            data.setLen(1);
            data.setPid(pid);
            data.setClassifyId(classifyId);
            data.setCodeModel(codeModel);
            data.setChildren(children);
            data.setParentId(parentId);
        }
        model.addAttribute("data", data);
        model.addAttribute("fieldList", fieldConfigs);
        return "/basic/setArchivesCodeFormat";
    }

    @Override
    public AjaxResult saveArchivesCodeList(HttpSession session, ArchivesCodeList data) {
        LoginUserInfo loginUser = redis.get(session.getId());

        if ("".equals(data.getFieldName())) {
            return AjaxResult.error("请选择组成字段");
        }
        if ("".equals(data.getId())) {
            data.setId(snowFlakeID.getId());
            long count = this.count(new QueryWrapper<ArchivesCodeList>()
                    .eq("pid", data.getPid()).eq("isdel", "0"));
            data.setIdx((int) (count + 1));
        }
        if (this.count(new QueryWrapper<ArchivesCodeList>().eq("pid", data.getPid())
                .eq("field_name", data.getFieldName())
                .eq("isdel", "0")
                .ne("id", data.getId())) > 0) {
            return AjaxResult.error("该组成字段已存在");
        }
        try {
            this.saveOrUpdate(data);
            if (createCodeFormat(loginUser, data.getPid(), data.getClassifyId(), data.getCodeModel(), data.getChildren(), data.getParentId())) {
                return AjaxResult.success("保存档号格式成功");
            } else {
                return AjaxResult.error("保存档号格式失败");
            }
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    @Override
    public AjaxResult delArchivesCodeFormat(String id) {
        if (archivesCodeFormatService.count(new QueryWrapper<ArchivesCodeFormat>()
                .eq("pid", id).eq("children", "1")) > 0) {
            return AjaxResult.error("该档案格式有下级数据，不可删除");
        }
        //使用事务统一提交
        DataSourceTransactionManager tran = new DataSourceTransactionManager(jdbcTemplate.getDataSource());
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        TransactionStatus status = tran.getTransaction(def);
        remove(new QueryWrapper<ArchivesCodeList>().eq("id", id));
        archivesCodeFormatService.remove(new QueryWrapper<ArchivesCodeFormat>().eq("id", id));
        try {
            tran.commit(status);
            return AjaxResult.success("删除档案格式成功");
        } catch (Exception e) {
            tran.rollback(status);
            return AjaxResult.error("删除档案格式失败，错误信息：" + e.getMessage());
        }
    }

    @Override
    public AjaxResult delArchivesCodeFormatList(HttpSession session, String id, String classifyId, String pid) {
        try {
            LoginUserInfo loginUser = redis.get(session.getId());
            this.remove(new QueryWrapper<ArchivesCodeList>().eq("id", id).eq("pid", pid));
            if (createCodeFormat(loginUser, pid, classifyId, "", "", "")) {
                return AjaxResult.success("删除档号格式成功");
            } else {
                return AjaxResult.error("删除档号格式失败");
            }
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    public boolean createCodeFormat(LoginUserInfo loginUser, String pid, String classifyId,
                                    String codeModel, String children, String parentId) {
        List<ArchivesCodeList> list = list(new QueryWrapper<ArchivesCodeList>()
                .eq("pid", pid)
                .eq("isdel", "0")
                .orderByAsc("idx"));
        String format = "";
        String doc = "";
        for (ArchivesCodeList codeList : list) {
            format = format + doc + '[' + codeList.getTitle() + ']';
            doc = codeList.getDoc();
        }
        if ("".equals(format)) {
            return archivesCodeFormatService.remove(new QueryWrapper<ArchivesCodeFormat>().eq("id", pid));
        }
        ArchivesClassify classify = classifyService.getById(classifyId);
        if (classify == null) {
            return false;
        }
        ArchivesCodeFormat codeFormat = archivesCodeFormatService.getOne(
                new QueryWrapper<ArchivesCodeFormat>().eq("id", pid)
        );
        if (codeFormat == null) {
            codeFormat = new ArchivesCodeFormat();
            codeFormat.setId(pid);
            codeFormat.setFillingModel(classify.getFillingModel());
            codeFormat.setClassifyId(classifyId);
            codeFormat.setCodeModel(codeModel);
            codeFormat.setCreateDate(LocalDateTime.now());
            codeFormat.setCreateer(loginUser.getUserName());
            codeFormat.setChildren(children);
            codeFormat.setPid(parentId);
        }
        codeFormat.setCodeFormat(format);
        codeFormat.setModifyer(loginUser.getUserName());
        codeFormat.setModifyDate(LocalDateTime.now());
        try {
            archivesCodeFormatService.saveOrUpdate(codeFormat);
            return true;
        } catch (Exception e) {
            log.error(e.getMessage());
            return false;
        }
    }
}
